import { Reducer, useCallback, useEffect, useReducer, useRef, useState } from "react";

interface Action {
  type: 'add' | 'minus',
  num: number
}

/* 使用 setState(prev => prev + 1) */

/* 使用reducer */
function reducer(state: number, action: Action) {

  switch (action.type) {
    case 'add':
      return state + action.num
    case 'minus':
      return state - action.num
  }
  return state;
}

function App1() {
  const [count, dispatch] = useReducer<Reducer<number, Action>>(reducer, 0);

  useEffect(() => {
    console.log(count);

    const timer = setInterval(() => {
      dispatch({ type: 'add', num: 1 })
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  return <div>{count}</div>;
}


/* 使用useRef */

function App2() {
  const [count, setCount] = useState(0)

  function updateCount() {
    setCount(count + 1)
  }



  const updateCountRef = useRef(updateCount)

  // 这里需要重新赋值下
  // useRef(fn); 初始化只会生效一次
  // ref.current = fn; 是为了保证fn每次变化都能替换
  updateCountRef.current = updateCount

  useEffect(() => {
    const timer = setInterval(() => {
      updateCountRef.current()
    }, 1000)
    return () => clearInterval(timer);
  }, [])

  return <div>{count}</div>
}


/* useInterval */
function useInterval(fn: () => void, time: number) {
  const ref = useRef(fn);

  ref.current = fn;

  const cleanUpFnRef = useRef<() => void>();

  // 调用者不能停止定时器，所以我们再加一个 ref 来保存 clean 函数，然后返回
  const clean = useCallback(() => {
    cleanUpFnRef.current?.();
  }, []);

  useEffect(() => {
    const timer = setInterval(() => ref.current(), time);

    cleanUpFnRef.current = () => {
      clearInterval(timer);
    }

    return clean;
  }, []);

  return clean;
}



export default App2;
